package com.zhsource.auth;

import cn.hutool.core.util.ObjUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @Description: 认证过滤器，也就是登录拦截器
 * @Author: Neuronet
 * @Date: 2023/10/6 18:49
 **/
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @SneakyThrows // 减少try-catch模板代码，在编译时生成
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1.从请求头中获取到token
        String tokenHeader = request.getHeader("Authorization");

        // 2.如果请求头中没有Authorization信息则直接放行了，交给后续的过滤器处理
        if (!StringUtils.hasLength(tokenHeader)) {
            chain.doFilter(request, response);
            return;
        }

        // 3.如果请求头中有token，则进行解析
        Payload payload = LoginJwtUtil.verifyAndGetUser(tokenHeader);

        // 4.如果解析失败，用户信息为null，则放行交给后续的过滤器处理
        if (ObjUtil.isEmpty(payload)) {
            log.error("从token中未获取到用户名, token：{}, URI：{}", tokenHeader, request.getServletPath());
            chain.doFilter(request, response);
            return;
        }

        // 5.用户信息不为Null则创建放行令牌
        // 5.1.获取到用户的权限集合
        List<String> permissionSn = payload.getPermissionSns();
        // 5.2 准备一个security所需要的承载权限的对象集合
        List<SimpleGrantedAuthority> grantedAuthorities = null;
        // 5.3 如果用户没有权限集合,说明是前台集合,那么不需要将权限集合转换为承载权限的对象集合
        if (!ObjUtil.isEmpty(permissionSn)) {
            grantedAuthorities = permissionSn.stream().map(SimpleGrantedAuthority::new).toList();
        }
        // 5.4 创建Security所需要的同行令牌
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(payload.getUser(), null, grantedAuthorities);

        // 5.5.设置令牌到安全上下文中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request, response);










//        // 5.用户信息不为Null则创建放行令牌
//        // 5.1.创建验证通过的令牌对象
//        List<String> permissionSn = payload.getPermissionSn();
//        UsernamePasswordAuthenticationToken authenticationToken = null;
//        if (ObjUtil.isEmpty(permissionSn)){
//            // 1.如果权限集合为空，那么说明是前台对象，则无需传入权限集合
//            authenticationToken = new UsernamePasswordAuthenticationToken(payload.getUser(), null, null);
//        }else {
//            // 2.如果权限集合不为空，则需要将权限集合转换为security所需要的集合对象
//            List<SimpleGrantedAuthority> grantedAuthorities = permissionSn.stream()
//                    .map(SimpleGrantedAuthority::new)
//                    .toList();
//            authenticationToken = new UsernamePasswordAuthenticationToken(payload.getUser(), null, grantedAuthorities);
//        }
//        // 5.2.设置令牌到安全上下文中
//        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//        chain.doFilter(request, response);
    }
}